package com.fuyd.pms.background.service.account;

import com.fuyd.pms.background.repository.LocalAuthDao;
import com.fuyd.pms.background.repository.MerchantUserDao;
import com.fuyd.pms.entity.account.LocalAuth;
import com.fuyd.pms.entity.account.MerchantUser;
import com.fuyd.pms.utils.Clock;
import com.fuyd.pms.utils.Digests;
import com.fuyd.pms.utils.Encodes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.security.NoSuchAlgorithmException;

/**
 * 账户管理的Service层
 * Created by fuyongde on 2015/12/26.
 */
@Service
public class AccountService {
    /**
     * 哈希算法：SHA-1算法
     **/
    public static final String HASH_ALGORITHM = "SHA-1";
    /**
     * 哈希算法长度
     **/
    public static final int HASH_INTERATIONS = 1024;
    /**
     * 密码随机盐的长度
     **/
    private static final int SALT_SIZE = 8;

    /**
     * 时间构造器
     **/
    private Clock clock = Clock.DEFAULT;

    /**
     * 用户Dao
     **/
    private MerchantUserDao merchantUserDao;
    /**
     * 用户名密码认证Dao
     **/
    private LocalAuthDao localAuthDao;

    @Autowired
    public void setMerchantUserDao(MerchantUserDao merchantUserDao) {
        this.merchantUserDao = merchantUserDao;
    }

    @Autowired
    public void setLocalAuthDao(LocalAuthDao localAuthDao) {
        this.localAuthDao = localAuthDao;
    }

    /**
     * 添加用户
     *
     * @param merchantUser
     */
    @Transactional
    public void registerUser(MerchantUser merchantUser, String password) throws NoSuchAlgorithmException {
        LocalAuth localAuth = new LocalAuth();
        localAuth.setUsername(merchantUser.getUsername());
        localAuth.setPassword(password);
        entryptPassword(localAuth);
        localAuth.setMerchantUser(merchantUser);
        merchantUser.setCreated(clock.getCurrentDate());
        merchantUser.setUpdated(clock.getCurrentDate());
        localAuth.setCreated(clock.getCurrentDate());
        localAuth.setUpdated(clock.getCurrentDate());
        merchantUserDao.save(merchantUser);
        localAuthDao.save(localAuth);
    }

    /**
     * 根据用户名查找用户
     *
     * @param username 用户名
     * @return 用户信息
     */
    public MerchantUser findMerchantUserByUsername(String username) {
        return merchantUserDao.findByUsername(username);
    }

    /**
     * 根据用户名查找账户名密码认证信息
     *
     * @param username
     * @return 用户名密码认证信息
     */
    public LocalAuth findLocalAuthByUsername(String username) {
        return localAuthDao.findByUsername(username);
    }

    /**
     * 更新用户
     *
     * @param merchantUser 更新用户
     */
    @Transactional
    public void update(MerchantUser merchantUser) {
        merchantUser.setUpdated(clock.getCurrentDate());
        merchantUserDao.save(merchantUser);
    }

    /**
     * 根据id查询用户
     *
     * @param id 用户id
     * @return 用户信息
     */
    public MerchantUser findById(String id) {
        return merchantUserDao.findOne(id);
    }

    /**
     * 设定安全的密码，生成随机的salt并经过1024次 sha-1 hash
     */
    private void entryptPassword(LocalAuth localAuth) throws NoSuchAlgorithmException {
        byte[] salt = Digests.generateSalt(SALT_SIZE);
        localAuth.setSalt(Encodes.encodeHex(salt));

        byte[] hashPassword = Digests.sha1(localAuth.getPassword().getBytes(), salt, HASH_INTERATIONS);
        localAuth.setPassword(Encodes.encodeHex(hashPassword));
    }
}
